package com.songqi.common.oss.config;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.amazonaws.util.StringUtils;
import com.songqi.common.oss.OssClient;
import com.songqi.common.oss.properties.S3Properties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.URL;
import java.util.Objects;

/**
 * @description:
 * @author: songqi(13776346982)
 * @date: 2023/12/13 08:53
 */
@ConditionalOnProperty(name = "s3.provider", havingValue = "aliyun")
@EnableConfigurationProperties(S3Properties.class)
@Slf4j
public class AliyunS3AutoConfiguration implements OssClient, InitializingBean, DisposableBean {

    @Resource
    private S3Properties s3Properties;

    private OSS ossClient;


    @Override
    public String upload(String bucket, String dir, MultipartFile file) {
        if (Objects.isNull(file)) {
            throw new IllegalArgumentException("文件不能为空!");
        }
        String objectName = UUID.fastUUID()+ file.getOriginalFilename();
        if(StrUtil.isNotBlank(dir)){
            if(! dir.endsWith("/")){
                dir = dir + "/" ;
            }
            if(dir.startsWith("/")){
                dir = dir.substring(1);
            }
            objectName = dir + objectName;
        }
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(file.getContentType());
        objectMetadata.setContentLength(file.getSize());
        bucket = StringUtils.isNullOrEmpty(bucket) ? s3Properties.getBucket() : bucket;
        try {
            PutObjectRequest request = new PutObjectRequest(bucket, objectName, file.getInputStream(), objectMetadata);
            PutObjectResult result = ossClient.putObject(request);
            log.info("文件上传结果：{}", JSONUtil.toJsonStr(result));

        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucket, objectName);
        URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
        return url.toString();
    }

    @Override
    public void destroy() throws Exception {
        if(ossClient != null){
            ossClient.shutdown();
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if(ossClient == null) {
            String endpoint = s3Properties.getEndpoint();
            String accessKey = s3Properties.getAccessKey();
            String secretKey = s3Properties.getSecretKey();
            String securityToken  = s3Properties.getSecurityToken();

            // 创建ClientConfiguration实例，按照您的需要修改默认参数。
            ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
            // 设置OSSClient允许打开的最大HTTP连接数，默认为1024个。
            conf.setMaxConnections(200);
            // 设置Socket层传输数据的超时时间，默认为50000毫秒。
            conf.setSocketTimeout(10000);
            // 设置建立连接的超时时间，默认为50000毫秒。
            conf.setConnectionTimeout(10000);
            // 设置从连接池中获取连接的超时时间（单位：毫秒），默认不超时。
            conf.setConnectionRequestTimeout(1000);
            // 设置连接空闲超时时间。超时则关闭连接，默认为60000毫秒。
            conf.setIdleConnectionTime(10000);
            // 设置失败请求重试次数，默认为3次。
            //  conf.setMaxErrorRetry(5);
            // 设置是否支持将自定义域名作为Endpoint，默认支持。
            //  conf.setSupportCname(true);
            // 设置是否开启二级域名的访问方式，默认不开启。
            //  conf.setSLDEnabled(true);
            // 设置连接OSS所使用的协议（HTTP/HTTPS），默认为HTTP。
            //  conf.setProtocol(Protocol.HTTP);
            // 设置用户代理，指HTTP的User-Agent头，默认为aliyun-sdk-java。
            //  conf.setUserAgent("aliyun-sdk-java");
            // 设置代理服务器端口。
            //   conf.setProxyHost("<yourProxyHost>");
            // 设置代理服务器验证的用户名。
            //  conf.setProxyUsername("<yourProxyUserName>");
            // 设置代理服务器验证的密码。
            //  conf.setProxyPassword("<yourProxyPassword>");
            ossClient =  new OSSClientBuilder().build(endpoint, accessKey, secretKey, conf);
            if(StrUtil.isNotBlank(s3Properties.getSecurityToken())) {
                ossClient = new OSSClientBuilder().build(endpoint, accessKey, secretKey, securityToken);
            }
        }
    }
}
